import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_common/ui/scaffold.dart';
import 'package:flutter_common/ui/widget/skeleton.dart';
import 'package:flutter_common/util/string_utils.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

import '../flutter_common.dart';

enum _BStatus {
  // ignore: constant_identifier_names
  Ready,
  // ignore: constant_identifier_names
  Empty,
  // ignore: constant_identifier_names
  Complete,
}

///列表支持下拉刷新，并可防止数组越界
abstract class ListViewSmartRefresherState<T extends StatefulWidget> extends SmartRefresherState<T> {

  @override
  Widget buildSmartRefresherBody(BuildContext context) {
    return ListView.separated(
        itemBuilder: (context, index) {
          if (index >= itemCount()) { //防止数组越界
            return const SizedBox();
          }
          return buildItem(context, index);
        },
        separatorBuilder: separatorBuilder,
        padding: listViewPadding(),
        itemCount: itemCount());
  }

  Widget separatorBuilder(BuildContext context, int index) {
    return const SizedBox();
  }

  EdgeInsetsGeometry? listViewPadding() => null;

  Widget buildItem(BuildContext context, int index);
  int itemCount();
}

abstract class SmartRefresherState<T extends StatefulWidget> extends State<T> with FxState, AutomaticKeepAliveClientMixin {
  RefreshController? _controller;
  late _BStatus _status = _BStatus.Ready;
  final bool enablePullDown, enablePullUp;
  final String? title;
  ///标题是否居中
  final bool? center;
  final String emptyText;

  SmartRefresherState(
      {this.title,
       this.center,
      this.enablePullDown = false,
      this.enablePullUp = false,
      this.emptyText = '暂无数据'});

  @override
  bool get wantKeepAlive => false;

  @override
  void initState() {
    super.initState();

    if (enablePullDown || enablePullUp) {
      _controller = RefreshController();
    }

    //有执行耗时操作，则先展示骨架屏，之后才展示数据
    if (enablePullDown) {
      onRefreshCallback();
    } else {
      _status = _BStatus.Complete;
    }
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    Widget body = getSmartRefresher(context);
    if (!title.isNullOrEmpty) {
      if(center == true) {
        body = FxScaffold.Center(body: body, title: title!);
      } else {
        body = FxScaffold(body: body, title: title);
      }
    }
    return body;
  }

  Widget getSmartRefresher(BuildContext context) {
    if (_BStatus.Ready == _status) {
      return const LoadingSkeleton();
    }
    Widget b = _status == _BStatus.Complete
        ? buildSmartRefresherBody(context)
        : buildEmptyBody(context);
    if (enablePullDown || enablePullUp) {
      return SmartRefresher(
          controller: _controller!,
          enablePullDown: enablePullDown,
          enablePullUp: (_status == _BStatus.Complete && enablePullUp),
          onRefresh: onRefreshCallback,
          onLoading: onLoadMoreCallback,
          header: const WaterDropHeader(),
          footer: const ClassicFooter(),
          child: b);
    }
    return b; //如果没开启刷新功能，则不需要 SmartRefresher
  }

  ///this function finish call [finishRefresh]
  void onRefreshCallback() {}

  ///this function finish call [finishRefresh]
  void onLoadMoreCallback() {}

  Widget buildSmartRefresherBody(BuildContext context);

  Widget buildEmptyBody(BuildContext context) {
    return Column(mainAxisAlignment: MainAxisAlignment.center, children: [
      Image.asset(
        "assets/smart_refresh_empty.png", //在派生项目中增加同名图片即可
      scale: 2),
      Text(emptyText)
    ]);
  }

  /// isNoMoreData = true 标记为没有更多数据上拉加载
  void finishRefresh(bool isEmpty, {bool isNoMoreData = false}) {
    _status = isEmpty ? _BStatus.Empty : _BStatus.Complete;
    mountedState();
    _controller?.refreshCompleted();
    if(isNoMoreData) {
      _controller?.loadNoData();
    } else {
      _controller?.loadComplete();
    }
  }

  /// 主动触发下拉刷新
  void requestRefresh({needMove: true}) {
    if(!mounted) {
      if (kDebugMode) {
        print("requestRefresh failure, but page call dispose(smart_refresh.dart)");
      }
      return;
    }
    if(_controller == null || _controller!.position == null) return;
    _controller!.requestRefresh(needMove: true);
  }
}
